package cn.open.feishu.alert.support;

import cn.open.feishu.alert.common.enums.AlertTypeEnum;
import cn.open.feishu.alert.common.param.CardDirectAlertParam;
import cn.open.feishu.alert.config.FeiShuProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.env.Environment;

import java.util.Objects;

/**
 * @Description 飞书机器人发送
 * @Author fandy.lin
 * @Date 2021/9/8 上午9:54
 **/
@Data
@Slf4j
@NoArgsConstructor
@AllArgsConstructor
public class FeishuAlertServiceImpl implements FeishuAlertService {
    private FeiShuProperties feiShuProperties;
    private CounterNativeCache counterCache;
    private FeishuAlertClient feishuAlertClient;
    private Environment env;

    @Override
    public void send(String alertText) {
        this.send(alertText, (Exception) null);
    }

    @Override
    public void send(Exception e) {
        String alertText = "";
        if (Objects.nonNull(e)) {
            alertText = e.getMessage();
        }
        this.send(null, alertText, e);
    }

    @Override
    public void send(String alertText, Exception e) {
        this.send(null, alertText, e);
    }

    @Override
    public void send(String robotName, String alertText) {
        this.send(robotName, alertText, null);
    }

    @Override
    public void send(String robotName, String alertText, Exception e) {
        try {
            this.sendAlert(robotName, null, alertText, alertText, e, AlertTypeEnum.TEXT_AlERT);
        } catch (Exception ex) {
            log.error("feishu alert:send immediate have error!", ex);
        }
    }

    @Override
    public void send(CardDirectAlertParam param) {
        if (feiShuProperties.getAsyncExecuteSwitch()) {
            feishuAlertClient.sendAsync(param);
        } else {
            feishuAlertClient.send(param);
        }
    }

    @Override
    public void sendAwait(String alertText) {
        this.sendAwait(alertText, (Exception) null);
    }

    @Override
    public void sendAwait(Exception e) {
        String alertText = "";
        if (e != null) {
            alertText = e.getMessage();
        }
        this.sendAwait(alertText, e);
    }

    @Override
    public void sendAwait(String alertText, Exception e) {
        this.sendAwait(null, alertText, e);
    }

    @Override
    public void sendAwait(String robotName, String alertText) {
        this.sendAwait(robotName, alertText, (Exception) null);
    }

    @Override
    public void sendAwait(String robotName, String alertText, Exception e) {
        try {
            this.sendAlert(robotName, feiShuProperties.getAwaitTime(), alertText, alertText, e, AlertTypeEnum.TEXT_AlERT);
        } catch (Exception ex) {
            log.error("feishu alert:send await have error!", ex);
        }
    }

    @Override
    public void sendAwait(String robotName, String pattern, String alertText) {
        this.sendAlert(robotName, feiShuProperties.getAwaitTime(), pattern, alertText, null, AlertTypeEnum.ERROR_LOG_ALERT);
    }

    private Boolean isEnableSend(Long seconds, String regexText) {
        if (feiShuProperties.getIsEnable() == false) {
            return false;
        }
        if (feiShuProperties.getRobotConfig() == null || feiShuProperties.getRobotConfig().isEmpty()) {
            log.warn("feishu alert:no robot configuration!");
            return false;
        }
        if (seconds == null) {
            return true;
        }
        if (counterCache.isIncrCountLimit(regexText)) {
            return true;
        }
        return false;
    }

    private void sendAlert(String robotName, Long seconds, String pattern, String alertText, Exception e, AlertTypeEnum alertType) {
        if (!isEnableSend(seconds, pattern)) {
            return;
        }
        if (feiShuProperties.getAsyncExecuteSwitch()) {
            feishuAlertClient.sendAsync(robotName, buildText(alertText, e), alertType);
        } else {
            feishuAlertClient.send(robotName, buildText(alertText, e), alertType);
        }
    }

    private String buildText(String alertText, Exception e) {
        StringBuilder textBulider = new StringBuilder();
        if (alertText != null) {
            textBulider.append(alertText);
        }
        if (e != null) {
            textBulider.append(">>").append(e);
        }
        return textBulider.toString();
    }
}